import React from 'react';
import {Table} from 'antd';
import {DragDropContext, DragSource, DropTarget} from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import update from 'immutability-helper';
import Lng from '../common/lng';
import TypeService from '../dishTypeInterval/Service';
import Merge from 'extend';

function dragDirection(dragIndex,
                       hoverIndex,
                       initialClientOffset,
                       clientOffset,
                       sourceClientOffset,) {
    const hoverMiddleY = (initialClientOffset.y - sourceClientOffset.y) / 2;
    const hoverClientY = clientOffset.y - sourceClientOffset.y;
    if (dragIndex < hoverIndex && hoverClientY > hoverMiddleY) {
        return 'downward';
    }
    if (dragIndex > hoverIndex && hoverClientY < hoverMiddleY) {
        return 'upward';
    }
}

let BodyRow = (props) => {
    const {
        isOver,
        connectDragSource,
        connectDropTarget,
        moveRow,
        dragRow,
        clientOffset,
        sourceClientOffset,
        initialClientOffset,
        ...restProps
    } = props;
    const style = {...restProps.style, cursor: 'move'};

    let className = restProps.className;
    if (isOver && initialClientOffset) {
        const direction = dragDirection(
            dragRow.index,
            restProps.index,
            initialClientOffset,
            clientOffset,
            sourceClientOffset
        );
        if (direction === 'downward') {
            className += ' drop-over-downward';
        }
        if (direction === 'upward') {
            className += ' drop-over-upward';
        }
    }

    return connectDragSource(
        connectDropTarget(
            <tr
                {...restProps}
                className={className}
                style={style}
            />
        )
    );
};

const rowSource = {
    beginDrag(props) {
        return {
            index: props.index,
        };
    },
};

const rowTarget = {
    drop(props, monitor) {
        const dragIndex = monitor.getItem().index;
        const hoverIndex = props.index;

        // Don't replace items with themselves
        if (dragIndex === hoverIndex) {
            return;
        }

        // Time to actually perform the action
        props.moveRow(dragIndex, hoverIndex);

        // Note: we're mutating the monitor item here!
        // Generally it's better to avoid mutations,
        // but it's good here for the sake of performance
        // to avoid expensive index searches.
        monitor.getItem().index = hoverIndex;
    },
};

BodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
    connectDropTarget: connect.dropTarget(),
    isOver: monitor.isOver(),
    sourceClientOffset: monitor.getSourceClientOffset(),
}))(
    DragSource('row', rowSource, (connect, monitor) => ({
        connectDragSource: connect.dragSource(),
        dragRow: monitor.getItem(),
        clientOffset: monitor.getClientOffset(),
        initialClientOffset: monitor.getInitialClientOffset(),
    }))(BodyRow)
);

const columns = [{
    title: Lng.get("dishTypSeq.code"),
    dataIndex: 'code',
    key: 'code',
}, {
    title: Lng.get("dishTypSeq.name"),
    dataIndex: 'name',
    key: 'name',
}, {
    title: Lng.get("dishTypSeq.seq"),
    dataIndex: 'sequence',
    key: 'sequence',
}];

class DishTypeSeq extends React.Component {
    state = {
        data: [],
    }

    components = {
        body: {
            row: BodyRow,
        },
    }

    loadData() {
        const self = this;
        TypeService.listTypes((data) => {
            self.setState({
                data: data.data
            });
        });
    }

    componentDidMount() {
        this.loadData();
    }

    moveRow = (dragIndex, hoverIndex) => {
        const {data} = this.state;
        const dragRow = data[dragIndex];

        const self = this;
        this.setState(
            update(this.state, {
                data: {
                    $splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]],
                },
            }), () => {
                let ds = self.refs["table"].props.dataSource;
                let tempDs = Merge([], ds, true);
                tempDs.forEach((t, i) => {
                    if (tempDs[i]) {
                        tempDs[i].sequence = (i + 1);
                    }
                });
                TypeService.updateTypes(tempDs, (data) => {
                    self.setState({
                        data: data.data
                    });
                });
            }
        );
    }

    render() {
        return (
            <Table
                ref={"table"}
                title={() => Lng.get("dishTypSeq.tips")}
                columns={columns}
                dataSource={this.state.data}
                components={this.components}
                pagination={false}
                onRow={(record, index) => ({
                    index,
                    moveRow: this.moveRow,
                })}
            />
        );
    }
}

const _DishTypeSeq = DragDropContext(HTML5Backend)(DishTypeSeq);

export default _DishTypeSeq;